package com.cencat.route.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.common.result.Result;
import com.cencat.route.entity.RouteInvoice;
import com.cencat.route.service.RouteInvoiceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 路线发票管理控制器
 * 提供路线发票管理的REST API接口
 * 
 * @author cencat
 * @version 1.0
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/route/invoice")
@Tag(name = "路线发票管理", description = "路线发票管理相关接口")
public class RouteInvoiceController {

    @Autowired
    private RouteInvoiceService routeInvoiceService;

    /**
     * 分页查询路线发票
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询路线发票", description = "根据条件分页查询路线发票信息")
    public Result<Page<RouteInvoice>> getRouteInvoicePage(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "路线ID") @RequestParam(required = false) Long routeId,
            @Parameter(description = "发票类型") @RequestParam(required = false) String invoiceType,
            @Parameter(description = "发票状态") @RequestParam(required = false) String status) {
        try {
            Page<RouteInvoice> page = routeInvoiceService.getRouteInvoicePage(current, size, routeId, invoiceType, status);
            return Result.success(page);
        } catch (Exception e) {
            log.error("分页查询路线发票失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 条件查询路线发票
     */
    @PostMapping("/search")
    @Operation(summary = "条件查询路线发票", description = "根据复杂条件查询路线发票")
    public Result<List<RouteInvoice>> searchRouteInvoices(@RequestBody Map<String, Object> conditions) {
        try {
            List<RouteInvoice> invoices = routeInvoiceService.searchRouteInvoices(conditions);
            return Result.success(invoices);
        } catch (Exception e) {
            log.error("条件查询路线发票失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID查询路线发票
     */
    @GetMapping("/{id}")
    @Operation(summary = "根据ID查询路线发票", description = "根据发票ID查询详细信息")
    public Result<RouteInvoice> getRouteInvoiceById(@PathVariable @NotNull Long id) {
        try {
            RouteInvoice invoice = routeInvoiceService.getById(id);
            return Result.success(invoice);
        } catch (Exception e) {
            log.error("根据ID查询路线发票失败, id: {}", id, e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 创建路线发票
     */
    @PostMapping
    @Operation(summary = "创建路线发票", description = "创建新的路线发票")
    public Result<Boolean> createRouteInvoice(@RequestBody RouteInvoice routeInvoice) {
        try {
            boolean result = routeInvoiceService.save(routeInvoice);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建路线发票失败", e);
            return Result.error("创建失败: " + e.getMessage());
        }
    }

    /**
     * 更新路线发票
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新路线发票", description = "更新路线发票信息")
    public Result<Boolean> updateRouteInvoice(@PathVariable @NotNull Long id, @RequestBody RouteInvoice routeInvoice) {
        try {
            routeInvoice.setId(id);
            boolean result = routeInvoiceService.updateById(routeInvoice);
            return Result.success(result);
        } catch (Exception e) {
            log.error("更新路线发票失败, id: {}", id, e);
            return Result.error("更新失败: " + e.getMessage());
        }
    }

    /**
     * 删除路线发票
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除路线发票", description = "根据ID删除路线发票")
    public Result<Boolean> deleteRouteInvoice(@PathVariable @NotNull Long id) {
        try {
            boolean result = routeInvoiceService.removeById(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("删除路线发票失败, id: {}", id, e);
            return Result.error("删除失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新发票类型
     */
    @PutMapping("/batch/type")
    @Operation(summary = "批量更新发票类型", description = "批量更新多个发票的类型")
    public Result<Boolean> batchUpdateInvoiceType(@RequestBody Map<String, Object> params) {
        try {
            @SuppressWarnings("unchecked")
            List<Long> ids = (List<Long>) params.get("ids");
            String invoiceType = (String) params.get("invoiceType");
            boolean result = routeInvoiceService.batchUpdateInvoiceType(ids, invoiceType);
            return Result.success(result);
        } catch (Exception e) {
            log.error("批量更新发票类型失败", e);
            return Result.error("更新失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新税率
     */
    @PutMapping("/batch/tax-rate")
    @Operation(summary = "批量更新税率", description = "批量更新多个发票的税率")
    public Result<Boolean> batchUpdateTaxRate(@RequestBody Map<String, Object> params) {
        try {
            @SuppressWarnings("unchecked")
            List<Long> ids = (List<Long>) params.get("ids");
            BigDecimal taxRate = new BigDecimal(params.get("taxRate").toString());
            boolean result = routeInvoiceService.batchUpdateTaxRate(ids, taxRate);
            return Result.success(result);
        } catch (Exception e) {
            log.error("批量更新税率失败", e);
            return Result.error("更新失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新发票金额
     */
    @PutMapping("/batch/amount")
    @Operation(summary = "批量更新发票金额", description = "批量更新多个发票的金额")
    public Result<Boolean> batchUpdateInvoiceAmount(@RequestBody Map<String, Object> params) {
        try {
            @SuppressWarnings("unchecked")
            List<Long> ids = (List<Long>) params.get("ids");
            BigDecimal amount = new BigDecimal(params.get("amount").toString());
            boolean result = routeInvoiceService.batchUpdateInvoiceAmount(ids, amount);
            return Result.success(result);
        } catch (Exception e) {
            log.error("批量更新发票金额失败", e);
            return Result.error("更新失败: " + e.getMessage());
        }
    }

    /**
     * 开具发票
     */
    @PostMapping("/issue/{id}")
    @Operation(summary = "开具发票", description = "开具指定的发票")
    public Result<Boolean> issueInvoice(@PathVariable @NotNull Long id) {
        try {
            boolean result = routeInvoiceService.issueInvoice(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("开具发票失败, id: {}", id, e);
            return Result.error("开具失败: " + e.getMessage());
        }
    }

    /**
     * 作废发票
     */
    @PostMapping("/void/{id}")
    @Operation(summary = "作废发票", description = "作废指定的发票")
    public Result<Boolean> voidInvoice(@PathVariable @NotNull Long id) {
        try {
            boolean result = routeInvoiceService.voidInvoice(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("作废发票失败, id: {}", id, e);
            return Result.error("作废失败: " + e.getMessage());
        }
    }

    /**
     * 红冲发票
     */
    @PostMapping("/red-flush/{id}")
    @Operation(summary = "红冲发票", description = "红冲指定的发票")
    public Result<Boolean> redFlushInvoice(@PathVariable @NotNull Long id) {
        try {
            boolean result = routeInvoiceService.redFlushInvoice(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("红冲发票失败, id: {}", id, e);
            return Result.error("红冲失败: " + e.getMessage());
        }
    }

    /**
     * 审核发票
     */
    @PostMapping("/audit/{id}")
    @Operation(summary = "审核发票", description = "审核指定的发票")
    public Result<Boolean> auditInvoice(@PathVariable @NotNull Long id) {
        try {
            boolean result = routeInvoiceService.auditInvoice(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("审核发票失败, id: {}", id, e);
            return Result.error("审核失败: " + e.getMessage());
        }
    }

    /**
     * 认证发票
     */
    @PostMapping("/authenticate/{id}")
    @Operation(summary = "认证发票", description = "认证指定的发票")
    public Result<Boolean> authenticateInvoice(@PathVariable @NotNull Long id) {
        try {
            boolean result = routeInvoiceService.authenticateInvoice(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("认证发票失败, id: {}", id, e);
            return Result.error("认证失败: " + e.getMessage());
        }
    }

    /**
     * 获取发票统计分析
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取发票统计分析", description = "获取发票的统计分析数据")
    public Result<Map<String, Object>> getInvoiceStatistics(
            @Parameter(description = "开始时间") @RequestParam(required = false) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) LocalDateTime endTime) {
        try {
            Map<String, Object> statistics = routeInvoiceService.getInvoiceStatistics(startTime, endTime);
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取发票统计分析失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 获取税务分析
     */
    @GetMapping("/tax-analysis")
    @Operation(summary = "获取税务分析", description = "获取发票的税务分析数据")
    public Result<Map<String, Object>> getTaxAnalysis(
            @Parameter(description = "开始时间") @RequestParam(required = false) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) LocalDateTime endTime) {
        try {
            Map<String, Object> analysis = routeInvoiceService.getTaxAnalysis(startTime, endTime);
            return Result.success(analysis);
        } catch (Exception e) {
            log.error("获取税务分析失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 合规性检查
     */
    @PostMapping("/compliance-check")
    @Operation(summary = "合规性检查", description = "对发票进行合规性检查")
    public Result<Map<String, Object>> complianceCheck(@RequestBody Map<String, Object> params) {
        try {
            Map<String, Object> result = routeInvoiceService.complianceCheck(params);
            return Result.success(result);
        } catch (Exception e) {
            log.error("合规性检查失败", e);
            return Result.error("检查失败: " + e.getMessage());
        }
    }

    /**
     * 获取待开具发票列表
     */
    @GetMapping("/pending")
    @Operation(summary = "获取待开具发票列表", description = "获取所有待开具的发票")
    public Result<List<RouteInvoice>> getPendingInvoices() {
        try {
            List<RouteInvoice> invoices = routeInvoiceService.getPendingInvoices();
            return Result.success(invoices);
        } catch (Exception e) {
            log.error("获取待开具发票列表失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 获取已开具发票列表
     */
    @GetMapping("/issued")
    @Operation(summary = "获取已开具发票列表", description = "获取所有已开具的发票")
    public Result<List<RouteInvoice>> getIssuedInvoices() {
        try {
            List<RouteInvoice> invoices = routeInvoiceService.getIssuedInvoices();
            return Result.success(invoices);
        } catch (Exception e) {
            log.error("获取已开具发票列表失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 获取已作废发票列表
     */
    @GetMapping("/voided")
    @Operation(summary = "获取已作废发票列表", description = "获取所有已作废的发票")
    public Result<List<RouteInvoice>> getVoidedInvoices() {
        try {
            List<RouteInvoice> invoices = routeInvoiceService.getVoidedInvoices();
            return Result.success(invoices);
        } catch (Exception e) {
            log.error("获取已作废发票列表失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 检查发票是否存在
     */
    @GetMapping("/exists/{invoiceNumber}")
    @Operation(summary = "检查发票是否存在", description = "根据发票号码检查发票是否存在")
    public Result<Boolean> checkInvoiceExists(@PathVariable @NotNull String invoiceNumber) {
        try {
            boolean exists = routeInvoiceService.checkInvoiceExists(invoiceNumber);
            return Result.success(exists);
        } catch (Exception e) {
            log.error("检查发票是否存在失败, invoiceNumber: {}", invoiceNumber, e);
            return Result.error("检查失败: " + e.getMessage());
        }
    }
}